#include "Sys.h"

Sys::Sys(void)
	:mainLog("EngineSystem.log"), initSuccess(true)
{
}


Sys::~Sys(void)
{
}

void Sys::Init()
{
	sysStart = GetLocalTime();

	DebugWriteLine("Adventure Engine Start");

	CheckSystemVersion();
	CheckRootDir();
	CheckCpu();
	CheckRam();

	if(initSuccess) {
		initialized = true;
	}

}

void Sys::Shutdown()
{
	initialized = false;
}

bool Sys::IsInitialized()
{
	return initialized;
}

LocalTime Sys::GetLocalTime()
{
	LocalTime time;
	SYSTEMTIME sysTime;

	::GetLocalTime(&sysTime);

	time.year = sysTime.wYear;
	time.month = sysTime.wMonth;
	time.day = sysTime.wDay;
	time.hour = sysTime.wHour;
	time.minute = sysTime.wMinute;
	time.second = sysTime.wSecond;
	time.milisecond = sysTime.wMilliseconds;

	return time;

}
	
std::string Sys::ConvertTimeToString(LocalTime time)
{
	std::stringstream ss;

	ss << L"Date:" << time.day << L'.' << time.month << L'.' << time.year << L'.' << _CRLF;
	ss << L"Time" << time.hour << L':' << time.minute << L':' << time.second << L'.' << time.milisecond << _CRLF;

	return ss.str();
}

void Sys::DebugWriteLine(const char* msg)
{
	LocalTime time = GetLocalTime();
	std::stringstream ss;
	
	ss << "T_" << time.hour << ':' << time.minute << ':' << time.second << '.' << time.milisecond << ' ' << msg << _CRLF;

#if defined(DEBUG) | defined(_DEBUG)
	Con::Write(ss.str());
#endif
	mainLog.Write(ss.str());
}

void Sys::DebugWriteLine(std::string msg)
{
	DebugWriteLine(msg.c_str());
}

void Sys::DebugPrintf(const char* format, ...)
{
	char msg[4096] = {};

	LocalTime time = GetLocalTime();
	std::stringstream ss;

	va_list args;
	va_start(args, format);

	if( _vsnprintf_s(msg, sizeof(msg), format, args) != -1)
	{
		ss << "T_" << time.hour << ':' << time.minute << ':' << time.second << '.' << time.milisecond << ' ' << msg;

#if defined(DEBUG) | defined(_DEBUG)
		Con::Write(ss.str());
#endif
		mainLog.Write(ss.str());

	}

	va_end(args);
}

void Sys::CheckSystemVersion()
{
	DWORD version = GetVersion();
	
	majorVer = (u8)(LOBYTE(LOWORD(version)));
	minorVer = (u8)(HIBYTE(LOWORD(version)));

	DebugPrintf("Windows version: %u.%u \n", majorVer, minorVer);

	if(majorVer < 6)
	{
		DebugPrintf("Needed at least Windows 7 \n");
		initSuccess = false;
	}
 
}

u16 Sys::GetSystemVersion()
{
	return (u16)((majorVer << 8) | (minorVer));
}

void Sys::CheckRootDir()
{
	if(GetCurrentDirectory(4096, rootDir) == 0)
	{
		Con::Write("Cannot check root directory");
		initSuccess = false;
	}

	DebugPrintf("Game directory: %s \n", rootDir);
}
	
std::string Sys::GetRootDir()
{
	std::string s(rootDir);
	return s;
}

void Sys::CheckCpu()
{
	SysCPU sc;

	processorInfo = sc.GetCPUInformation();

	DebugPrintf("CPU: %dMHz, %d cores \n",processorInfo.mhz, processorInfo.numLogicalProcessors);

	if(processorInfo.architecture == X86)
	{
		DebugPrintf("CPU X86\n");
	}

	if(processorInfo.architecture == X64)
	{
		DebugPrintf("CPU X64\n");
	}

	//features
	if(processorInfo.features & MMX)
	{
		DebugPrintf("MMX\n");
	}

	if(processorInfo.features & SSE)
	{
		DebugPrintf("SSE\n");
	}

	if(processorInfo.features & SSE2)
	{
		DebugPrintf("SSE2\n");
	}

	if(processorInfo.features & SSE3)
	{
		DebugPrintf("SSE3\n");
	}

	if(processorInfo.features & _3D_NOW)
	{
		DebugPrintf("3D_NOW\n");
	}

}

CPUInfo Sys::GetCpuInfo()
{
	return processorInfo;
}

void Sys::CheckRam()
{
	SysRam ram;

	ramInfo = ram.GetMemoryInfo();

	DebugPrintf("Ram: %dKB \n", ramInfo.physMemTotal);
}

RamInfo Sys::GetRamInfo()
{
	return ramInfo;
}

void Sys::MsgBoxInfo(const char* msg)
{
	MessageBox(NULL, msg, "Information", MB_OK | MB_ICONINFORMATION);
}

void Sys::MsgBoxWarning(const char* msg)
{
	MessageBox(NULL, msg, "Warning!", MB_OK | MB_ICONWARNING);
}
	
void Sys::MsgBoxError(const char* msg)
{
	MessageBox(NULL, msg, "ERROR!", MB_OK | MB_ICONERROR);
}